package core;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionAdapter;
import java.beans.PropertyVetoException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;

import javax.swing.JDesktopPane;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;

public class BoardPane extends JDesktopPane implements MouseListener,ActionListener {
	private Rectangle mouseRect;
	private static List<PostIt> nodes;
	private static final int WIDE = 800;
    private static final int HIGH = 600;
    private List<PostIt> selected;
    private boolean selecting = false;
    private Point mousePt;
    private JPopupMenu popup;
    
	
	public static List<PostIt> getNodes() {
		return nodes;
	}

	public static void setNodes(List<PostIt> nodes) {
		BoardPane.nodes = nodes;
	}

	
	public BoardPane() {
		mouseRect = new Rectangle();
		
		popup = new JPopupMenu();
		JMenuItem menuItem = new JMenuItem("Regroup");
        menuItem.addActionListener(this);
        popup.add(menuItem);
        
		nodes = new ArrayList<PostIt>();
		selected = new ArrayList<PostIt>();
		mousePt = new Point(WIDE / 2, HIGH / 2);
		
		setDragMode(OUTLINE_DRAG_MODE);
		this.setSize(WIDE,HIGH);
		this.setLayout(null);
		this.addMouseMotionListener(new MouseMotionHandler());
		this.addMouseListener(this);
	}
	
	public void actionPerformed(ActionEvent e) {
        String cmd = e.getActionCommand();
        System.out.println("Inside action performed.");
        if ("Regroup".equals(cmd)) {
        	System.out.println("Regroup selected");
        	PostIt.getSelect(nodes, selected);
        	System.out.println("Size of selected: "+selected.size());
        	//Sort it from most recent to least recent
        	Collections.sort(selected);
        	if (selected.size() > 1) {
        		// Coordinates of the most recent postit amongst the ones selected
        		int decrementX = selected.get(0).getX();
        		int decrementY = selected.get(0).getY();
        		int count =0;
        		
        		while(true) {
        			count++;
        			for(int i=0; i<selected.size(); i++) {
        				decrementY = decrementY-20;
        			}
        			if(decrementY>0)
        				break;
        			else 
        				decrementY = selected.get(0).getY()+(count*20);
        		}
        		
        		if(count==1) decrementY = selected.get(0).getY();
        		else decrementY = selected.get(0).getY()+(20*count);
        		
        		count = 0;
        		while(true) {
        			count++;
        			for(int i=0; i<selected.size(); i++) {
        				decrementX = decrementX-15;
        			}
        			if(decrementX>0)
        				break;
        			else 
        				decrementX = selected.get(0).getX()+(count*15);
        		}
        		
        		if(count==1) decrementX = selected.get(0).getX();
        		else decrementX = selected.get(0).getX()+(15*count);
        		
                for (int i = 0; i < selected.size(); i++) {
                	PostIt current = selected.get(i);
                	current.reshape(decrementX, decrementY, current.getWidth(), 
                			current.getHeight());
                	decrementX = decrementX-15;
                	decrementY = decrementY-20;
                }
                for(int i=selected.size()-1; i>-1; i--) {
                	PostIt current = selected.get(i);
                	try {
						current.setSelected(true);
					} catch (PropertyVetoException e1) {
						e1.printStackTrace();
					}
                	current.toFront();
                }
        	}
        }
        for(PostIt pi:nodes) {
        	pi.getArea().setBackground(Color.getHSBColor(60, 20, 20));
        }
        this.repaint();
    }

		
	@Override
	public void mouseClicked(MouseEvent arg0) {
		//Double Click event
		if(arg0.getClickCount()>1) {
			if(arg0.getX()<775 && arg0.getY()<600) {
				PostIt pi = new PostIt(arg0.getX(), arg0.getY());
				nodes.add(pi);
				updatePanel();
				repaint();
				pi.getArea().requestFocusInWindow();
				setFocusable(false);
			}
		}
	}
    
    private void updatePanel() {
    	this.removeAll();
    	ListIterator<PostIt> iter = nodes.listIterator();
    	while(iter.hasNext()) {
    		this.add(iter.next());
    	}
    }

	@Override
	public void mouseEntered(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mouseExited(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void mousePressed(MouseEvent e) {
		if(!SwingUtilities.isRightMouseButton(e)) {
			for(PostIt pi:nodes) {
				pi.getArea().setBackground(Color.getHSBColor(60, 20, 20));
			}
		}
		 mousePt = e.getPoint();
         if (e.isShiftDown()) {
             PostIt.selectToggle(nodes, mousePt);
         } else if (e.isPopupTrigger()) {
             showPopup(e);
         } else {
             selecting = true;
         }
         e.getComponent().repaint();		
	}

	@Override
	public void mouseReleased(MouseEvent e) {
		selecting = false;
        mouseRect.setBounds(0, 0, 0, 0);
        if (e.isPopupTrigger()) {
            showPopup(e);
        }
        e.getComponent().repaint();		
	}
	
	@Override
    public void paintComponent(Graphics g) {
        g.setColor(Color.LIGHT_GRAY);
        g.fillRect(0, 0, getWidth(), getHeight());
        if (selecting) {
            g.setColor(Color.darkGray);
            g.drawRect(mouseRect.x, mouseRect.y,
                mouseRect.width, mouseRect.height);
        }
    }
	
	private void showPopup(MouseEvent e) {
        popup.show(e.getComponent(), e.getX(), e.getY());
    }
	
    private class MouseMotionHandler extends MouseMotionAdapter {

        Point delta = new Point();

        @Override
        public void mouseDragged(MouseEvent e) {
            if (selecting) {
                mouseRect.setBounds(
                    Math.min(mousePt.x, e.getX()),
                    Math.min(mousePt.y, e.getY()),
                    Math.abs(mousePt.x - e.getX()),
                    Math.abs(mousePt.y - e.getY()));
                PostIt.selectRect(nodes, mouseRect);
                
            } else {
                delta.setLocation(
                    e.getX() - mousePt.x,
                    e.getY() - mousePt.y);
                mousePt = e.getPoint();
            }
            e.getComponent().repaint();
        }
    }
}